from flask import Flask, request, jsonify, Response
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
from openai import OpenAI
from rec_movie import MovieRecommender
from audio import TextToSpeech

app = Flask(__name__)
CORS(app)

# DeepSeek的访问API
ds_client = OpenAI(api_key="sk-5b2ecd0180d04171a458c6a9af63dc6e", base_url="https://api.deepseek.com")

# 讯飞云语音合成的API
tts = TextToSpeech(app_id='13431e25', api_key='dbf3ef69306fa3f7099aa0012ac85122',
                   api_secret='ZDExYmZkZmE2ZmE4MzFmZjdjOTgwNjcx')

# 配置数据库链接信息
HOSTNAME = "127.0.0.1"
PORT = 3306
USERNAME = "root"
PASSWORD = "root"
DATABASE = "imrs"
app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8"
db = SQLAlchemy(app)

# 创建推荐对象，并进行初始化
movie_recommender = MovieRecommender(db)
with app.app_context():
    movie_recommender.preprocess_data()


# 电影信息
class Movie(db.Model):
    __tablename__ = 'movies'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(255))
    year = db.Column(db.Integer)
    region = db.Column(db.String(100))
    director = db.Column(db.String(255))
    type = db.Column(db.String(100))
    rating = db.Column(db.Numeric(10, 1))
    poster = db.Column(db.String(255))


# 用户信息
class User(db.Model):
    __tablename__ = 'users'
    username = db.Column(db.String(255), primary_key=True)
    nickname = db.Column(db.String(255))
    password = db.Column(db.String(255))
    preferregion = db.Column(db.String(255))
    prefertype = db.Column(db.String(255))


# 用户注册
@app.route('/register', methods=['POST'])
def register():
    data = request.get_json()
    username = data.get('username')
    nickname = data.get('nickname')
    password = data.get('password')

    # 判断传入的参数是否为空
    if not username or not password:
        return jsonify({'success': False, 'message': '用户名和密码不能为空'})

    # 检测用户名是否存在
    existing_user = User.query.filter_by(username=username).first()
    if existing_user:
        return jsonify({'success': False, 'message': '用户名已存在'})

    # 写入数据库，返回注册结果
    try:
        new_user = User(username=username, nickname=nickname, password=password, preferregion='', prefertype='')
        db.session.add(new_user)
        db.session.commit()
        return jsonify({'success': True, 'message': '注册成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': '注册失败'})


# 用户登录
@app.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    if not username or not password:
        return jsonify({'success': False, 'message': '用户名和密码不能为空'})

    user = User.query.filter_by(username=username).first()
    if not user or user.password != password:
        return jsonify({'success': False, 'message': '用户名或密码错误'})
    return jsonify({
        'success': True,
        'message': '登录成功',
        'user': {
            'username': user.username,
            'nickname': user.nickname,
            'preferregion': user.preferregion,
            'prefertype': user.prefertype
        }
    })


# 用户更新昵称和密码
@app.route('/profile/update', methods=['POST'])
def update_profile():
    data = request.get_json()
    username = data.get('username')
    nickname = data.get('nickname')
    password = data.get('password')

    # 检查用户名是否为空
    if not username:
        return jsonify({'success': False, 'message': '用户名不能为空'})

    # 查询用户是否存在
    user = User.query.filter_by(username=username).first()
    if not user:
        return jsonify({'success': False, 'message': '用户不存在'})

    try:
        # 更新昵称和密码
        if nickname is not None:
            user.nickname = nickname
        if password is not None:
            user.password = password

        # 提交更改到数据库
        db.session.commit()
        return jsonify({'success': True, 'message': '用户信息更新成功'})
    except Exception as e:
        # 回滚事务
        db.session.rollback()
        return jsonify({'success': False, 'message': '用户信息更新失败'})


# 用户更新偏好信息
@app.route('/profile/prefers', methods=['POST'])
def update_prefers():
    data = request.get_json()
    username = data.get('username')
    preferregion = data.get('preferregion')
    prefertype = data.get('prefertype')

    try:
        user = User.query.filter_by(username=username).first()
        if not user:
            return jsonify({'success': False, 'message': '用户不存在'})

        user.preferregion = preferregion
        user.prefertype = prefertype
        db.session.commit()
        return jsonify({'success': True, 'message': '偏好更新成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': '偏好更新失败'})


# 根据id获取电影信息
@app.route('/movie/<int:movie_id>', methods=['GET'])
def get_movie(movie_id):
    movie = db.session.get(Movie, movie_id)
    if not movie:
        return jsonify({'success': False, 'message': '电影不存在'})

    return jsonify({
        'success': True,
        'movie': {
            'id': movie.id,
            'title': movie.title,
            'year': movie.year,
            'region': movie.region,
            'director': movie.director,
            'type': movie.type,
            'rating': float(movie.rating) if movie.rating else None,
            'poster': movie.poster
        }
    })


# 获取电影信息列表
@app.route('/movies', methods=['GET'])
def get_movies():
    # 获取查询参数
    page = request.args.get('page', default=1, type=int)
    per_page = request.args.get('per_page', default=10, type=int)
    search = request.args.get('search', default='', type=str)
    type_filter = request.args.get('type', default=None, type=str)

    # 构建基础查询
    query = Movie.query

    # 应用搜索条件
    if search:
        query = query.filter(Movie.title.like(f'%{search}%'))
    if type_filter:
        query = query.filter(Movie.type.like(f'%{type_filter}%'))

    # 分页
    pagination = query.paginate(page=page, per_page=per_page, error_out=False)
    movies = pagination.items

    # 准备返回数据
    movies_data = [{
        'id': movie.id,
        'title': movie.title,
        'year': movie.year,
        'region': movie.region,
        'director': movie.director,
        'type': movie.type,
        'rating': float(movie.rating) if movie.rating else None,
        'poster': movie.poster
    } for movie in movies]

    return jsonify({
        'success': True,
        'movies': movies_data,
        'total': pagination.total,
        'pages': pagination.pages,
        'current_page': pagination.page
    })


# 获取所有国家地区和类型
@app.route('/regions_types', methods=['GET'])
def get_regions():
    return jsonify({
        'success': True,
        'regions': sorted(list(movie_recommender.all_regions)),
        'types': sorted(list(movie_recommender.all_types))
    })


# 内部函数，根据多个id获取对应电影信息列表
def _get_movies_data(rec_ids):
    """根据推荐ID列表获取电影数据"""
    movies = Movie.query.filter(Movie.id.in_(rec_ids)).all()
    return [{
        'id': movie.id,
        'title': movie.title,
        'year': movie.year,
        'region': movie.region,
        'director': movie.director,
        'type': movie.type,
        'rating': float(movie.rating) if movie.rating else None,
        'poster': movie.poster
    } for movie in movies]


# 根据国家地区和类型进行推荐
@app.route('/rec_by_region_type', methods=['GET'])
def get_rec_by_region_type():
    region = request.args.get('region', default='', type=str)
    type = request.args.get('type', default='', type=str)
    rec_ids = movie_recommender.rec_by_region_and_type(region, type)
    return jsonify({
        'success': True,
        'movies': _get_movies_data(rec_ids)
    })


# 根据电影进行推荐
@app.route('/rec_by_movie', methods=['GET'])
def get_rec_by_movie():
    movie = request.args.get('movie', default='', type=str)
    rec_ids = movie_recommender.rec_by_movie(movie)
    return jsonify({
        'success': True,
        'movies': _get_movies_data(rec_ids)
    })


# 用AI生成电影简介
@app.route('/ai_des', methods=['GET'])
def ai_description():
    title = request.args.get('title', default='', type=str)
    year = request.args.get('year', default=1, type=int)
    director = request.args.get('director', default='', type=str)

    if title == '':
        return jsonify({"description": "电影信息无效"})

    try:
        response = ds_client.chat.completions.create(
            model="deepseek-chat",
            messages=[
                {"role": "system", "content": "你是一个专业的电影评论家，请用中文为电影生成一段精彩的简介。"},
                {"role": "user", "content": f"请为电影《{title}》({year}年，导演：{director})写一段200字左右的简介"}
            ],
            temperature=0.7
        )
        description = response.choices[0].message.content
        return jsonify({"description": description})
    except Exception as e:
        return jsonify({"error": str(e)}), 500


# 语音合成
@app.route('/tts', methods=['GET'])
def text_to_speech():
    text = request.args.get('text', default='', type=str)
    if not text:
        return jsonify({'success': False, 'message': '请输入要合成的文本'})

    try:
        output_data = tts.synthesize(text)
        if output_data:
            # 返回二进制数据，设置正确的MIME类型
            return Response(
                output_data,
                mimetype='audio/mpeg',  # MP3标准MIME类型
                headers={'Content-Disposition': 'attachment; filename=tmp.mp3'}
            )
        return jsonify({'success': False, 'message': '语音合成失败'})
    except Exception as e:
        return jsonify({'success': False, 'message': str(e)})


if __name__ == '__main__':
    app.run(debug=True)
